#include "xn297l.h"
#include "spi.h"

#define CE_PORT (PortB)
#define CE_PIN (Pin09)
#define CSN_PORT (PortB)
#define CSN_PIN (Pin08)

#define CE_L PORT_ResetBits(CE_PORT, CE_PIN)
#define CE_H PORT_SetBits(CE_PORT, CE_PIN)
#define CSN_L PORT_ResetBits(CSN_PORT, CSN_PIN)
#define CSN_H PORT_SetBits(CSN_PORT, CSN_PIN)

//单个包的数据长度
#define PAYLOAD_WIDTH 16 // Payload宽度：     <=20bytes
//使用增强型模式
#define TRANSMIT_TYPE TRANS_ENHANCE_MODE
#define DATA_RATE DR_1M //通信速率1Mbps            DR_2M    DR_1M
//#define RF_POWER (RF13dBm|DATA_RATE)		//发射功率13dBm
#define RF_POWER (RF10dBm | DATA_RATE) //发射功率10dBm
////////////////////////////////////////////////////////////////////////////////
//                    以下为声明部分，不建议修改                              //
////////////////////////////////////////////////////////////////////////////////
#define TRANS_ENHANCE_MODE 1 //传输类型增强型
#define TRANS_BURST_MODE 2   //传输类型普通型

#define RF13dBm 0x3f  // 44//0x3F                            // 13dBm
#define RF10dBm 0X17  // 10dBm
#define RF8dBm 0x15   // 8dbm
#define RF7dBm 0x07   // 7dbm
#define RF5dBm 0x2c   // 5dbm
#define RF4dBm 0x06   // 4dbm
#define RF2dBm 0x05   // 2dbm
#define RF0dBm 0X0B   // 0dBm
#define RF_3dBm 0x04  // -3dBm
#define RF_6dBm 0x0A  // -6dBm
#define RF_10dBm 0x02 // -10dBm
#define RF_18dBm 0x01 // -18dBm
#define RF_30dBm 0x00 // -30dBm

/********************SPI  REGISTER  ********************/
#define R_REGISTER 0x00         // SPI read RF data
#define W_REGISTER 0x20         // SPI write RF data
#define R_RX_PAYLOAD 0x61       // Read RX Payload
#define W_TX_PAYLOAD 0xA0       // Write TX Payload
#define FLUSH_TX 0xE1           // Flush RX FIFO
#define FLUSH_RX 0xE2           // Flush TX FIFO
#define REUSE_TX_PL 0xE3        // Reuse TX Payload
#define ACTIVATE 0x50           // ACTIVATE
#define DEACTIVATE 0x50         // DEACTIVATE
#define R_RX_PL_WID 0x60        // Read width of RX data
#define W_ACK_PAYLOAD 0xA8      // Data with ACK
#define W_TX_PAYLOAD_NOACK 0xB0 // TX Payload no ACK Request
#define CE_FSPI_ON 0xFD         // CE HIGH
#define CE_FSPI_OFF 0xFC        // CE LOW
#define RST_FSPI 0x53           // RESET
#define NOP_N 0xFF
#define TX_DS 0x20
/******************CONTROL  REGISTER*******************/
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define STATUS 0x07
#define OBSERVE_TX 0x08
#define RPD 0x09
#define RX_ADDR_P0 0x0A
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
#define DEM_CAL 0x19
#define RF_CAL2 0x1A
#define DEM_CAL2 0x1B
#define DYNPD 0x1C
#define FEATURE 0x1D
#define RF_CAL 0x1E
#define BB_CAL 0x1F
#define uint8_t unsigned char
/////////////////////////////////////////////////////////////////////////////////////
/*************************CONTROL CMD****************************************/
#define DR_1M 0X00   //通信速率 1Mbps
#define DR_2M 0X40   //通信速率 2Mbps
#define DR_250K 0XC0 //通信速率 2Mbps

static void xn297lWriteReg(uint8_t reg, uint8_t wdata)
{
    CSN_L;
    spiRW(reg);
    spiRW(wdata);
    CSN_H;
}

static uint8_t xn297lReadReg(uint8_t reg)
{
    CSN_L;
    spiRW(reg);
    reg = spiRW(0);
    CSN_H;
    return reg;
}

// 写的起始地址是 W_REGISTER
static void xn297lWriteBuf(uint8_t reg, uint8_t *pBuf, uint8_t length)
{
    int i;
    CSN_L;
    spiRW(reg);
    for (i = 0; i < length; i++)
    {
        spiRW(pBuf[i]);
    }
    CSN_H;
}

// 读的起始地址比写的起始地址少 W_REGISTER
static void xn297lReadBuf(uint8_t reg, uint8_t *pBuf, uint8_t length)
{
    int i;
    CSN_L;
    spiRW(reg);
    for (i = 0; i < length; i++)
    {
        pBuf[i] = spiRW(0);
    }
    CSN_H;
}

static void gpioConfig(void)
{
    stc_port_init_t stcPortInit;
    MEM_ZERO_STRUCT(stcPortInit);
    stcPortInit.enPinMode = Pin_Mode_Out;
    PORT_Init(CE_PORT, CE_PIN, &stcPortInit);
    PORT_Init(CSN_PORT, CSN_PIN, &stcPortInit);
    CSN_H;
}


static void regConfig(uint8_t *addr)
{
    uint8_t BB_cal_data[] = {0x2a, 0xec, 0x6f, 0x9c, 0x46};
    uint8_t RF_cal_data[] = {0xf6, 0x37, 0x5d};
    uint8_t RF_cal2_data[] = {0xd5, 0x21, 0xef, 0x2c, 0x5a, 0x40};
    uint8_t Dem_cal_data[] = {0x01};
    uint8_t Dem_cal2_data[] = {0x0b, 0xdf, 0x02};

    CE_L;
    xn297lWriteReg(RST_FSPI, 0x5A); // Software Reset
    xn297lWriteReg(RST_FSPI, 0XA5);
    xn297lWriteReg(FLUSH_RX, 0);                           // CLEAR  RXFIFO
    xn297lWriteReg(FLUSH_TX, 0);                           // CLEAR TXFIFO
    xn297lWriteReg(W_REGISTER + STATUS, 0x70);             // CLEAR  STATUS
    xn297lWriteReg(W_REGISTER + EN_RXADDR, 0x01);          // Enable Pipe0
    xn297lWriteReg(W_REGISTER + SETUP_AW, 0x03);           // address witdth is 5 bytes
    xn297lWriteReg(W_REGISTER + RF_CH, DEFAULT_CHANNEL);   // 2478M HZ
    xn297lWriteReg(W_REGISTER + RX_PW_P0, PAYLOAD_WIDTH);  // 32 bytes
    // 初始化本机地址
    xn297lWriteBuf(W_REGISTER + TX_ADDR, addr, 5);    // Writes TX_Address to PN006
    xn297lWriteBuf(W_REGISTER + RX_ADDR_P0, addr, 5); // RX_Addr0 same as TX_Adr for Auto.Ack

    xn297lWriteBuf(W_REGISTER + BB_CAL, BB_cal_data, sizeof(BB_cal_data));
    xn297lWriteBuf(W_REGISTER + RF_CAL2, RF_cal2_data, sizeof(RF_cal2_data));
    xn297lWriteBuf(W_REGISTER + DEM_CAL, Dem_cal_data, sizeof(Dem_cal_data));
    xn297lWriteBuf(W_REGISTER + RF_CAL, RF_cal_data, sizeof(RF_cal_data));
    xn297lWriteBuf(W_REGISTER + DEM_CAL2, Dem_cal2_data, sizeof(Dem_cal2_data));

    xn297lWriteReg(W_REGISTER + DYNPD, 0x00);
    xn297lWriteReg(W_REGISTER + RF_SETUP, RF_POWER); // DBM


    xn297lWriteReg(ACTIVATE, 0x73);                //如果使用W_ACK则需要这句
    xn297lWriteReg(W_REGISTER + SETUP_RETR, 0x01); //  3 retrans...
    xn297lWriteReg(W_REGISTER + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
    xn297lWriteReg(W_REGISTER + FEATURE, 0x02);

    xn297lWriteReg(W_REGISTER + CONFIG, 0XBF); // 将RF设置成RX模式

    CE_H; //拉高CE,配置完毕，使能开始
    Ddl_Delay1ms(5);
}

// 判断芯片是否存在
static uint8_t existenceFlagxn297l = 0;
uint8_t xn297lInit(void)
{
    gpioConfig();

    // 检测 xn297l 是否连接
    uint8_t t_regVal = xn297lReadReg(0x0f);
    if(0xc6 == t_regVal)
    {
        uint8_t t_addr[] = {1,1,2,2,3};
        regConfig(t_addr);
        existenceFlagxn297l = 1;
    }

    return existenceFlagxn297l;
}

uint8_t xn297lReadAndSend(uint8_t *pRBuf, uint8_t *pTBuf)
{
    uint8_t result = 0;
    if (existenceFlagxn297l)
    {
        uint8_t t_status = xn297lReadReg(STATUS);
        if ((t_status & 0x40) > 0) // 需要读取数据
        {
            xn297lReadBuf(R_RX_PAYLOAD, pRBuf, PAYLOAD_WIDTH);
            xn297lWriteReg(FLUSH_RX, 0);
            xn297lWriteReg(W_REGISTER + STATUS, 0x40); //清除Status
            //回馈数据给TX端, 本地的xn297l发送回馈数据完后, 会再次产生发送完成中断
            xn297lWriteBuf(W_ACK_PAYLOAD, pTBuf, PAYLOAD_WIDTH);
            result = 1;
        }

        if ((t_status & 0x30) > 0)
        { // 发送完成的中断
            xn297lWriteReg(FLUSH_TX, 0);
            xn297lWriteReg(W_REGISTER + STATUS, 0x30); //清除Status
        }
    }
		
    return result;
}

/*
 *Input: 新通道值
 *Description: 改变收发通道（0~78）
 *Return: void
 */
void xn297lSetChannel(uint8_t t_channel)
{
    xn297lWriteReg(W_REGISTER + RF_CH, t_channel);
}

// 设置地址
void xn297lSetAddr(uint8_t *t_addr)
{
    regConfig(t_addr);
}

void xn297lClose(void)
{
    CE_L;
}

void xn297lOn(void)
{
    CE_H;
}
